<template>
<div>
  <el-table
    ref="table"
    header-row-class-name="base-table-header-v3"
    row-class-name="base-table-row-v3"
    :class="['multiple-card-table',  isShowCardMultiSave && 'task-multiple-card-table', isHoursRecord && 'hours-record']"
    :data="disposeFormListViewTimeList"
    row-key="id"
    border>
    <template slot="empty">
      <BaseListForNoData
        v-show="!listLoading"
        table-type="smallTable"
        :notice-msg="$t('common.base.tip.noData')"
      ></BaseListForNoData>
    </template>
    <el-table-column type="index" width="50" :label="$t('common.base.SN')" />
    <el-table-column
      v-for="(column, index) in getColumns"
      :key="column.fieldId"
      :label="column.displayName"
      :prop="column.fieldName"
      :fixed="column.fixed"
      :min-width="column.minWidth || (isShowCardMultiSave ? '220px': '120px')"
      show-overflow-tooltip>
      <template slot-scope="scope">

        <!-- start 添加行 -->
        <template v-if="mouseEnterEditRow(column, scope.row) && !isHoursRecord">
          <div class="rows-form-builder" v-if="column.formType !== 'jsCodeBlock'">
            <form-builder
              :ref="`${column.fieldName}_${scope.$index}_${column.displayName}`"
              :fields="[getColumnField(scope.row, column, scope.$index)]"
              :value="scope.row"
              @update="(obj) => updateRow(obj, scope.$index)"
            >
            </form-builder>
            <template v-if="jsCodeBlockHiddenFields.length && index === 0">
              <form-js-control
                v-for="jsCodeBlockField in jsCodeBlockHiddenFields"
                class="form-js-control__hidden"
                :key="jsCodeBlockField.fieldId + scope.$index" 
                :field="jsCodeBlockField" 
                :formAllValue="{taskData: task, ...scope.row}" 
                :formAllFields="currentColumnsMap[scope.row.id]"
                @update="handleJsCodeBlockUpdate($event, scope.$index, scope.row)"
                inLineTable />
            </template>
          </div>
          <div class="rows-form-builder" v-else>
              <form-js-control
                :key="column.fieldId + scope.$index" 
                :field="column" 
                :formAllValue="{taskData: task, ...scope.row}" 
                :formAllFields="currentColumnsMap[scope.row.id]"
                @update="handleJsCodeBlockUpdate($event, scope.$index, scope.row)"
                inLineTable></form-js-control>
          </div>
        </template>
        <!-- end 添加行 -->

        <template v-else>
          <!-- start 产品 -->
          <template v-if="column.fieldName === 'taskCardRelationProduct'">
            {{ scope.row[column.fieldName]?scope.row[column.fieldName][0].name:'' }}
          </template>
          <!-- end 产品 -->

          <!-- start 工单状态 -->
          <template v-else-if="column.fieldName === 'state'">
            {{ stateText(scope.row) || '' }}
          </template>
          <!-- end 工单状态 -->

          <!-- start 附件类型 -->
          <template v-else-if="column.formType === 'attachment'">
            <span class="column-attachment" v-if="scope.row[column.fieldName] && scope.row[column.fieldName].length">
              <i class="iconfont icon-attachment"></i> 
              {{$t('task.detail.components.attachmentNum', {num: scope.row[column.fieldName].length})}}
            </span>
          </template>
          <!-- end 附件类型 -->
          
          <template v-else-if="column.formType === 'user'">
                
            <template v-if="isOpenData">
              <template v-if="Array.isArray(scope.row[column.fieldName])">
                <open-data v-for="item in scope.row[column.fieldName]" :key="item.staffId" type="userName" :openid="item.staffId"></open-data>
              </template>
              <template v-else>
                <open-data type="userName" :openid="scope.row[column.fieldName] && scope.row[column.fieldName].staffId"></open-data>
              </template>
            </template>
                
            <template v-else>
              {{ $formatFormField(column, scope.row) }}
            </template>
            
          </template>
          
          <!-- start 多选 -->
          <template v-else-if="isMulti(column)">
            {{ (scope.row[column.fieldName] || []).join('，') }}
          </template>
          <!-- end 多选 -->

          <!-- start 位置 -->
          <template v-else-if="isHoursRecord && column.fieldName === 'location'">
            <el-button
              type="text"
              size="mini"
              v-if="scope.row.fromType == 2"
              @click="handleEvent('location', data[scope.$index])"
            >查看</el-button>
          </template>
          <!-- end 位置 -->
          
          <!-- start 操作人 -->
          <template v-else-if="column.fieldName === 'userName'">
            <template v-if="isOpenData">
              <open-data type="userName" :openid="scope.row.staffId"></open-data>
            </template>
            
            <template v-else>
              {{ scope.row[column.fieldName] }}
            </template>
          </template>
          <!-- end 操作人 -->
          
          <!-- start 操作人 -->
          <template v-else-if="column.fieldName === 'operatorName'">
            <template v-if="isOpenData">
              <open-data type="userName" :openid="scope.row.operatorStaffId"></open-data>
            </template>
            
            <template v-else>
              {{ scope.row[column.fieldName] }}
            </template>
          </template>
          <!-- end 操作人 -->

          <!-- start 操作时间 -->
          <template v-else-if="column.fieldName === 'updateTime'">
            {{ scope.row[column.fieldName] | fmt_datetime }}
          </template>
          <!-- end 操作时间 -->

          <!-- start 操作 -->
          <template v-else-if="column.fieldName === 'action'">
            <template v-if="isShowCardMultiSave && !isHoursRecord">
              <el-button
                v-if="allowDelete"
                type="text"
                size="small"
                @click="handleCardMultiDeleteEvent(scope.row, scope.$index)"
              >
                {{$t('common.base.delete')}}
              </el-button>
            </template>
            <template v-else>
              <el-dropdown class="dropdown" v-if="(showEditBtn(scope.row) || allowDelete) && (shareData && !shareData.isArchive)">
                <span class="cur-point">
                  {{$t('common.base.more')}}<i class="el-icon-arrow-down el-icon--right"></i>
                </span>
                <el-dropdown-menu slot="dropdown" class="lang-select-dropdown" :class="[ isHoursRecord && 'hours-record-action']">
                  <el-dropdown-item><div @click="handleEvent('view', data[scope.$index])">{{$t('common.base.detail')}}</div></el-dropdown-item>
                  <el-dropdown-item><div v-if="showEditBtn(scope.row)" @click="handleEvent('edit',  data[scope.$index], scope.$index)">{{$t('common.base.edit')}}</div></el-dropdown-item>
                  <el-dropdown-item><div v-if="allowDelete" @click="handleEvent('delete', data[scope.$index], scope.$index)">{{$t('common.base.delete')}}</div></el-dropdown-item>
                </el-dropdown-menu>
              </el-dropdown>
              <div v-else>
                <el-button
                  type="text"
                  size="mini"
                  @click="handleEvent('view', scope.row)"
                >{{$t('common.base.detail')}}</el-button>
              </div>
            </template>
          </template>
          <!-- end 操作 -->

          <template v-else>
            {{ $formatFormField(column, scope.row) }}
          </template>
        </template>
      </template>
    </el-table-column>
  </el-table>

    <!-- 底部数据量统计 -->
     <div class="table-footer">
      <i18n path="common.base.table.totalCount">
        <span place="count" class="level-padding">{{tableData.length || 0}}</span>
      </i18n>
    </div>
</div>
</template>

<script>
import { isOpenData } from '@src/util/platform'
import { useFormTimezone, uuid } from 'pub-bbx-utils'
import TaskStateEnum from '@model/enum/TaskStateEnum.ts';
import { FieldTypeMappingEnum } from '@model/enum/FieldMappingEnum';
import { getRootWindow } from '@src/util/dom';
import i18n from '@src/locales';
import { matchFormField } from 'src/component/form/components/FormJsControl/model/index'
import { cloneDeep } from 'lodash'
import validator from '@src/util/validator'

export default {
  name: 'multiple-card-table',
  data() {
    return {
      isOpenData,
      isMouseInArray: [],
      tableData: [],
      currentColumnsMap: {} // 暂时这样解决 数据量大可能会有性能问题
    }
  },
  props: {
    data: {
      type: Array,
      default: () => ([])
    },
    columns: {
      type: Array,
      default: () => ([])
    },
    listLoading: {
      type: Boolean,
      default: true
    },
    isHoursRecord: {
      type: Boolean,
      default: false
    },
    allowCreate: {
      type: Boolean,
      default: false
    },
    allowEdit: {
      type: Boolean,
      default: false
    },
    allowDelete: {
      type: Boolean,
      default: false
    },
    shareData:{
      type:Object,
      default:()=>({})
    },
    task: {
      type:Object,
      default:()=>({})
    }
  },
  computed: {
    // 开启添加行灰度
    isShowCardMultiSave() {
      const RootWindow = getRootWindow(window)
      return RootWindow?.grayAuth?.CARD_MULTI_SAVE;
    },
    getColumns() {
      return this.columns.filter(item => !this.unsupportedFormType(item));
    },
    jsCodeBlockHiddenFields() {
      return this.columns.filter(field => field.formType === FieldTypeMappingEnum.JsCodeBlock && !!field.setting?.hidden);
    },
    existJsBlockField() {
      return this.columns.some(field => field.formType === FieldTypeMappingEnum.JsCodeBlock)
    },
    disposeFormListViewTimeList() {
      return this.disposeFormListViewTime(this.tableData, this.columns)
    }
  },
  watch: {
    data: {
      immediate: true,
      handler(newValue, oldValue) {
        if(this.isShowCardMultiSave) {
          newValue.forEach(item => {
            if(item.operateType !== 'save') {
              item.allowEdit = this.allowEdit;
            }
          });
          this.tableData = newValue.filter(item => item.operateType !== 'delete');
          this.$nextTick(() => {
            this.$refs.table?.doLayout()
          })
        } else {
          this.tableData = newValue;
        }


        if(this.existJsBlockField) {
          this.tableData.forEach(item=> {
              if(!Reflect.get(this.currentColumnsMap, item.id)) {
                  this.currentColumnsMap[item.id] = cloneDeep(this.getColumns)
              }
            })
        }
   
        this.getFormBuilderKey();
      }
    }
  },
  methods: {
    getColumnField(row, column, index) {
      if(!this.existJsBlockField) return column
      return this.currentColumnsMap[row.id]?.find(item=> item.fieldName === column.fieldName)
    },

    /**
     * Description 代码块更新的时候更新的组件
     * @param {any} field
     * @returns {any}
     */
    handleUpdateTableFormLinkJsCodeBlock(field, id) {
      try {
        const matchFormFieldResult = matchFormField(field, this.currentColumnsMap[id])
          for(let [k, v] of Object.entries(this.$refs)) {
            const existOrderFieldNameField = matchFormFieldResult.find(item=> k.includes(item.fieldName))
            if(existOrderFieldNameField && v[0]) {
              v[0].componentKey = uuid()
            }
          }
      } catch(err) {
        console.error('[handleUpdateTableFormLinkJsCodeBlock error]', err)
      }
    },

    /**
     * Description 代码块的组件更新事件
     * @param {any} {field}
     * @param {any} index
     * @param {any} tableRow
     * @returns {any}
     */
    handleJsCodeBlockUpdate({field}, index, tableRow) {
      this.$emit('update', {
        fieldName:'',
        newValue: tableRow,
        index,
        updateRow: true
      })
      this.handleUpdateTableFormLinkJsCodeBlock(field, tableRow.id)
    },
    // 不支持在列表编辑的字段
    unsupportedFormType(item) {
      if (!item) return false;
      const { formType } = item
      if(formType === FieldTypeMappingEnum.JsCodeBlock) {
        return !!item.setting?.hidden
      }
      return [
        FieldTypeMappingEnum.Autograph,
        FieldTypeMappingEnum.Address,
        FieldTypeMappingEnum.Location,
        FieldTypeMappingEnum.RelatedTask,
        FieldTypeMappingEnum.Attachment,
      ].includes(formType);
    },
    // 不支持在列表编辑的字段
    unsupportedFieldName(fieldName) {
      return [
        'userName', 
        'updateTime',
        'action',
      ].includes(fieldName);
    },
    mouseEnterEditRow(column, row) {

      return this.isShowCardMultiSave // 灰度
      && !this.unsupportedFieldName(column.fieldName) // 非不支持字段
      && !this.unsupportedFormType(column.formType) // 非不支持字段
      && (row.operateType === 'save' || row.allowEdit); // 有编辑权限
    },
    getFormBuilderKey() {
      this.cleanCache();

      const fields = this.columns.filter(item => 
        !this.unsupportedFieldName(item.fieldName) && !this.unsupportedFormType(item.formType)
      );
      this.data.forEach((item, index) => {
        fields.forEach(field => {
          this.isMouseInArray.push(`${field.fieldName}_${index}_${field.displayName}`);
        });
      });
    },
    getRowIndex(row) {
      return this.data.findIndex(item => item.id === row.id);
    },
    updateRow({ field, newValue }, index) {
      const { fieldName } = field;
      this.$emit('update', {
        fieldName,
        newValue,
        index,
      })
    },
    async saveAddMultipleCardRow() {
      // 校验表单必填项
      let getPast = true;
      for(let i = 0; i < this.isMouseInArray.length; i++) {
        const form = this.isMouseInArray[i];
        if(this.$refs[form]?.length) {
          const validateRes = await this.$refs[form][0].validate(false);
          if (!validateRes) getPast = false;
        }
      }

      for(let i =0; i< this.disposeFormListViewTimeList.length; i++) {
        const itemValue = this.disposeFormListViewTimeList[i]
        const fields = (this.currentColumnsMap[itemValue.id] || []).concat(this.jsCodeBlockHiddenFields)
        const jsCodeBlockFields = fields.filter(item=> item.formType === FieldTypeMappingEnum.JsCodeBlock)

        for(let j = 0; j < jsCodeBlockFields.length; j++) {
          const jsCodeBlockField = jsCodeBlockFields[j]
          const jsCodeBlockValidatorRes = await validator.validate(itemValue[jsCodeBlockField.fieldName], jsCodeBlockField, itemValue)
          if(jsCodeBlockValidatorRes) getPast = false;
        }
      }

      if(!getPast) return;
      this.$emit('submit', this.data);
    },  
    ...useFormTimezone(),
    /** 
    * @description 显示编辑按钮
    * 1.附加组件是工时记录类型时，有编辑权限且是pc端数据
    * 2.普通附加组件有编辑权限
    */
    showEditBtn(row) {
      let editAuth = this.allowEdit;

      // 工时记录类型
      if (this.isHoursRecord) return editAuth && row.fromType == 1;

      return editAuth;
    },
    /** 
    * @description 字段是否是多选类型
    */
    isMulti(field) {
      let { formType, setting = {}} = field;
      if (formType === 'selectMulti') return true;
      if (formType === 'select' && setting.isMulti) return true;
      return false;
    },
    async handleCardMultiDeleteEvent(row, index) {
      let result = await this.$platform.confirm(i18n.t('task.tip.deleteTip'));
      if (!result) return;
      this.cleanCache();
      this.$emit('delete', row, index);
    },
    /** 
    * @description 附加组件操作
    */
    handleEvent(action, row, index) {
      let data = {
        cardInstance: row,
        action,
        rowIndex:index
      }

      this.$emit('action', data);
    },
    clearAllValidate() {
      // 清除表单校验
      for(let i = 0; i < this.isMouseInArray.length; i++) {
        const form = this.isMouseInArray[i];
        if(this.$refs[form]?.length) {
          this.$refs[form][0]?.clearAllValidate();
        }
      }
    },
    cleanCache() {
      this.isMouseInArray = [];
    },
    /** 工单状态*/
    stateText(value) {
      return TaskStateEnum.getNameForTask( value || {});
    },
  }
}
</script>

<style lang="scss" scoped>
.multiple-card-table {
  .base-table-row-v3 td {
    .column-attachment {
      .iconfont {
        font-size: 12px;
      }
    }

    .el-button {
      min-width: auto !important;
      padding: 0;
    }
  }
  .cur-point {
    color: $color-primary-light-6;
  }
}
.lang-select-dropdown {
  margin-top: 0!important;
}
</style>
<style lang="scss">
.task-multiple-card-table {
  .form-builder {
    padding: 0;
    input, textarea {
      border-color: #FFF;
    }
    input:hover, 
    textarea:hover {
      border-color: #7ddddd;
    }
    .form-item {
      margin-bottom: 0;
      .form-item-label {
        display: none;
      }
    }
    .form-textarea-summary {
      display: none;
    }
    .err-msg-wrap {
      display: none;
    }
    .form-user-clear {
      top: 40%;
    }
  }
  .el-table__body .el-table__row td .cell {
    height: 100%;
    min-height: 82px;
  }
  .el-table--small td {
    height: 100%;
  }
  .rows-form-builder {
    width: 100% !important;
    position: relative;
  }
}
.form-js-control__hidden{
  display: none;
  position: absolute;
  left: 0;
  top: 0;
}
.hours-record{
  .el-table__body .el-table__row td .cell {
    height: 100%;
    min-height: 30px;
    .el-button{
      font-size: 14px;
    }
  }
}
.hours-record-action{
  .el-dropdown-menu__item{
    width: auto !important;
  }
}
</style>
